#include "UART.h"
#if (UART1_EN || UART2_EN || UART3_EN || UART4_EN)

static uint8_t uart_busy[UART_USE_NUM_MAX] = {3}; // 0空闲，1忙中，2未初始化
static uint16_t uart_txd_ptr[UART_USE_NUM_MAX];
static uint16_t uart_txd_count[UART_USE_NUM_MAX]; // 发送数据递减

static uint16_t uart_rxdptr[UART_USE_NUM_MAX];
static uint16_t uart_readptr[UART_USE_NUM_MAX];
static uint16_t uart_rxd_count[UART_USE_NUM_MAX];
static uint16_t rx_buf_size[UART_USE_NUM_MAX];

#if UART1_EN
#if UART1_RXD_BUFFER_SIZE
static uint8_t uart1_rx_buf[UART1_RXD_BUFFER_SIZE];
static uint8_t *uart1_rx_buf_p = uart1_rx_buf;
#endif
static uint8_t uart1_tx_buf[UART1_TXD_BUFFER_SIZE];
#endif
#if UART2_EN
#if UART2_RXD_BUFFER_SIZE
static uint8_t uart2_rx_buf[UART2_RXD_BUFFER_SIZE];
static uint8_t *uart2_rx_buf_p = uart2_rx_buf;
#endif
static uint8_t uart2_tx_buf[UART2_TXD_BUFFER_SIZE];
#endif
#if UART3_EN
#if UART3_RXD_BUFFER_SIZE
static uint8_t uart3_rx_buf[UART3_RXD_BUFFER_SIZE];
static uint8_t *uart3_rx_buf_p = uart3_rx_buf;
#endif
static uint8_t uart3_tx_buf[UART3_TXD_BUFFER_SIZE];
#endif
#if UART4_EN
#if UART4_RXD_BUFFER_SIZE
static uint8_t uart4_rx_buf[UART4_RXD_BUFFER_SIZE];
static uint8_t *uart4_rx_buf_p = uart4_rx_buf;
#endif
static uint8_t uart4_tx_buf[UART4_TXD_BUFFER_SIZE];
#endif

#if (UART1_RXD_BUFFER_SIZE || UART2_RXD_BUFFER_SIZE || UART3_RXD_BUFFER_SIZE || UART4_RXD_BUFFER_SIZE)
void serial_set_rec_buffer(UART_TYPE uart_num, uint8_t *buffer, size_t size)
{
    switch (uart_num)
    {

#if (UART1_EN && UART1_RXD_BUFFER_SIZE)
    case uart1:
        if (buffer == NULL)
        {
            rx_buf_size[uart_num] = UART1_RXD_BUFFER_SIZE;
            uart1_rx_buf_p = uart1_rx_buf;
        }

        else
        {
            rx_buf_size[uart_num] = size;
            uart1_rx_buf_p = buffer;
        }
        break;
#endif

#if (UART2_EN && UART2_RXD_BUFFER_SIZE)
    case uart2:
        if (buffer == NULL)
        {
            rx_buf_size[uart_num] = UART2_RXD_BUFFER_SIZE;
            uart2_rx_buf_p = uart2_rx_buf;
        }

        else
        {
            rx_buf_size[uart_num] = size;
            uart2_rx_buf_p = buffer;
        }
#endif

#if (UART3_EN && UART3_RXD_BUFFER_SIZE)
    case uart3:
        if (buffer == NULL)
        {
            rx_buf_size[uart_num] = UART3_RXD_BUFFER_SIZE;
            uart3_rx_buf_p = uart3_rx_buf;
        }

        else
        {
            rx_buf_size[uart_num] = size;
            uart3_rx_buf_p = buffer;
        }
#endif

#if (UART4_EN && UART4_RXD_BUFFER_SIZE)
    case uart4:
        if (buffer == NULL)
        {
            rx_buf_size[uart_num] = UART4_RXD_BUFFER_SIZE;
            uart4_rx_buf_p = uart4_rx_buf;
        }

        else
        {
            rx_buf_size[uart_num] = size;
            uart4_rx_buf_p = buffer;
        }
#endif

    default:
        break;
    }
    uart_rxdptr[uart_num] = 0;
    uart_readptr[uart_num] = 0;
    uart_rxd_count[uart_num] = 0;
}
#endif

void serial_write(UART_TYPE uart_num, uint8_t dat)
{
    if (uart_busy[uart_num] == 2)
        return;
    while (uart_busy[uart_num])
        ;
    uart_busy[uart_num] = 1;

#if UART1_EN
    if (uart_num == uart1)
        SBUF = dat;
#endif
#if UART2_EN
    if (uart_num == uart2)
        S2BUF = dat;
#endif
#if UART3_EN
    if (uart_num == uart3)
        S3BUF = dat;
#endif
#if UART4_EN
    if (uart_num == uart4)
        S4BUF = dat;
#endif
}

void serial_write_bytes(UART_TYPE uart_num, uint8_t *dat, uint16_t size)
{
    static uint8_t *tmp = NULL;
    static uint16_t _size;
    static UART_TYPE _uart_num;
    _uart_num = uart_num;
    _size = size;
    tmp = dat;
    if (uart_busy[_uart_num] == 2)
        return;
#if UART1_EN
    if (_uart_num == uart1)
    {

        while (_size > UART1_TXD_BUFFER_SIZE)
        {
            serial_write(uart1, *tmp++);
            _size--;
        }
        while (uart_busy[_uart_num])
            ;
        memcpy(uart1_tx_buf, tmp, _size);
        uart_busy[uart1] = 1;
        SBUF = uart1_tx_buf[0];
    }
#endif
#if UART2_EN
    if (_uart_num == uart2)
    {
        while (_size > UART2_TXD_BUFFER_SIZE)
        {
            serial_write(uart2, *tmp++);
            _size--;
        }
        while (uart_busy[_uart_num])
            ;
        memcpy(uart2_tx_buf, tmp, _size);
        uart_busy[uart2] = 1;
        S2BUF = uart2_tx_buf[0];
    }
#endif
#if UART3_EN
    if (_uart_num == uart3)
    {
        while (_size > UART3_TXD_BUFFER_SIZE)
        {
            serial_write(uart3, *tmp++);
            _size--;
        }
        while (uart_busy[_uart_num])
            ;
        memcpy(uart3_tx_buf, tmp, _size);
        uart_busy[uart3] = 1;
        S3BUF = uart3_tx_buf[0];
    }
#endif
#if UART4_EN
    if (_uart_num == uart4)
    {
        while (_size > UART4_TXD_BUFFER_SIZE)
        {
            serial_write(uart4, *tmp++);
            _size--;
        }
        while (uart_busy[_uart_num])
            ;
        memcpy(uart4_tx_buf, tmp, _size);
        uart_busy[uart4] = 1;
        S4BUF = uart4_tx_buf[0];
    }
#endif

    uart_txd_ptr[_uart_num] = 1;
    uart_txd_count[_uart_num] = _size - 1;
}

#if UART1_EN
void UartIsr() interrupt 4
{
    if (TI)
    {
        TI = 0;

        if (uart_txd_count[uart1])
        {
            SBUF = uart1_tx_buf[uart_txd_ptr[uart1]++];
            uart_txd_count[uart1]--;
        }
        else
            uart_busy[uart1] = 0;
        return;
    }
    if (RI)
    {
        RI = 0;
#if UART1_RXD_BUFFER_SIZE
        uart1_rx_buf_p[uart_rxdptr[uart1]++] = SBUF;
        if (uart_rxdptr[uart1] == rx_buf_size[uart1])
            uart_rxdptr[uart1] = 0;
        uart_rxd_count[uart1]++;
#endif
    }
}

#endif

#if UART2_EN
void Uart2Isr() interrupt 8
{
    if (S2CON & 0x02)
    {
        S2CON &= ~0x02;
        if (uart_txd_count[uart2])
        {
            uart_txd_count[uart2]--;
            S2BUF = uart2_tx_buf[uart_txd_ptr[uart2]++];
        }
        else
            uart_busy[uart2] = 0;
        return;
    }
    if (S2CON & 0x01)
    {
        S2CON &= ~0x01;
#if UART2_RXD_BUFFER_SIZE
        uart2_rx_buf_p[uart_rxdptr[uart2]++] = S2BUF;
        if (uart_rxdptr[uart2] == rx_buf_size[uart2])
            uart_rxdptr[uart2] = 0;
        uart_rxd_count[uart2]++;
#endif
    }
}

#endif

#if UART3_EN
void Uart3Isr() interrupt 17
{
    if (S3CON & 0x02)
    {
        S3CON &= ~0x02;
        if (uart_txd_count[uart3])
        {
            uart_txd_count[uart3]--;
            S3BUF = uart3_tx_buf[uart_txd_ptr[uart3]++];
        }
        else
            uart_busy[uart3] = 0;
        return;
    }
    if (S3CON & 0x01)
    {
        S3CON &= ~0x01;
#if UART3_RXD_BUFFER_SIZE
        uart3_rx_buf_p[uart_rxdptr[uart3]++] = S3BUF;
        if (uart_rxdptr[uart3] == rx_buf_size[uart3])
            uart_rxdptr[uart3] = 0;
        uart_rxd_count[uart3]++;
#endif
    }
}
#endif

#if UART4_EN
void Uart4Isr() interrupt 18
{
    if (S4CON & 0x02)
    {
        S4CON &= ~0x02;
        if (uart_txd_count[uart4])
        {
            uart_txd_count[uart4]--;
            S4BUF = uart4_tx_buf[uart_txd_ptr[uart4]++];
        }
        else
            uart_busy[uart4] = 0;
        return;
    }
    if (S4CON & 0x01)
    {
        S4CON &= ~0x01;
#if UART4_RXD_BUFFER_SIZE
        uart4_rx_buf_p[uart_rxdptr[uart4]++] = S4BUF;
        if (uart_rxdptr[uart4] == rx_buf_size[uart4])
            uart_rxdptr[uart4] = 0;
        uart_rxd_count[uart4]++;
#endif
    }
}
#endif

uint8_t serial_begin(UART_TYPE uart_num, timer_type timer, unsigned long cpu_frq, unsigned long band)
{
    uint16_t brt;

    if (uart_busy[0] == 3)
    {
        for (brt = 0; brt < UART_USE_NUM_MAX; brt++)
            uart_busy[brt] = 2;
    }
    if (uart_busy[uart_num] != 2)
        return 1;

///////////////////////////////////////////////////
#if UART1_EN
    if (uart_num == uart1)
    {
#if UART1_RXD_BUFFER_SIZE
        SCON = 0x50;
#else
        SCON = 0x40;
#endif
        rx_buf_size[uart_num] = UART1_RXD_BUFFER_SIZE;
    }
#endif
#if UART2_EN
    if (uart_num == uart2)
    {
#if UART2_RXD_BUFFER_SIZE
        S2CON = 0x10;
#else
        S2CON = 0x00;
#endif
        rx_buf_size[uart_num] = UART2_RXD_BUFFER_SIZE;
    }
#endif
#if UART3_EN
    if (uart_num == uart3)
    {
#if UART3_RXD_BUFFER_SIZE
        S3CON = 0x10;
#else
        S3CON = 0x00;
#endif
        rx_buf_size[uart_num] = UART3_RXD_BUFFER_SIZE;
    }
#endif
#if UART4_EN
    if (uart_num == uart4)
    {
#if UART4_RXD_BUFFER_SIZE
        S4CON = 0x10;
#else
        S4CON = 0x00;
#endif
        rx_buf_size[uart_num] = UART4_RXD_BUFFER_SIZE;
    }
#endif

    //////////////////////////////////////////////////

    brt = (65536 - ((cpu_frq / band) >> 2));
    if (brt == 0)
        return 2;

/////////////////////////////////////////////////////////
#if UART1_EN
    if (timer == timer1)
    {
        if (uart_num != uart1)
            return 3;
        AUXR |= 0x40; // 定时器时钟1T模式
        TMOD &= 0x0F; // 设置定时器模式
        AUXR &= ~0X01;
        TL1 = brt;      // 设置定时初始值
        TH1 = brt >> 8; // 设置定时初始值
        TR1 = 1;
        ES = 1;
    }
#endif
#if UART3_EN
    if (timer == timer3)
    {
        if (uart_num != uart3)
            return 3;
        S3CON |= 0X40;
        T3L = brt;
        T3H = brt >> 8;
        T4T3M |= 0x0a;
        IE2 |= 0X08;
    }
#endif
#if UART4_EN
    if (timer == timer4)
    {
        if (uart_num != uart4)
            return 3;
        S4CON |= 0X40;
        T4L = brt;
        T4H = brt >> 8;
        T4T3M |= 0xA0;
        IE2 |= 0X10;
    }
#endif
    if (timer == timer2)
    {
        T2L = brt;
        T2H = brt >> 8;
        AUXR |= 0x14;
#if UART1_EN
        if (uart_num == uart1)
        {
            AUXR |= 0x01;
            ES = 1;
        }
#endif
#if UART2_EN
        if (uart_num == uart2)
            IE2 |= 0X01;
#endif
#if UART3_EN
        if (uart_num == uart3)
            IE2 |= 0X08;
#endif
#if UART4_EN
        if (uart_num == uart4)
            IE2 |= 0X10;
#endif
    }

    uart_rxdptr[uart_num] = 0;
    uart_readptr[uart_num] = 0;
    uart_rxd_count[uart_num] = 0;

    uart_txd_count[uart_num] = 0;
    uart_busy[uart_num] = 0;

    EA = 1;
    return 0;
}

void serial_end(UART_TYPE uart_num)
{
    if (uart_busy[uart_num] > 1)
        return;
    while (uart_busy[uart_num])
        ;
    uart_busy[uart_num] = 2;

#if UART1_EN
    if (uart_num == uart1)
        ES = 0;
#endif
#if UART2_EN
    if (uart_num == uart2)
        IE2 &= ~0X01;
#endif
#if UART3_EN
    if (uart_num == uart3)
        IE2 &= ~0X08;
#endif
#if UART4_EN
    if (uart_num == uart4)
        IE2 &= ~0X10;
#endif
}

uint16_t serial_available(UART_TYPE uart_num)
{
    return uart_rxd_count[uart_num];
}

uint16_t serial_chek_busy(UART_TYPE uart_num)
{
    return uart_txd_count[uart_num];
}

uint8_t Serial_read(UART_TYPE uart_num)
{
    uint8_t tmp;
    if (uart_rxd_count[uart_num] == 0)
        return 0;
    uart_rxd_count[uart_num]--;
#if (UART1_EN && UART1_RXD_BUFFER_SIZE)
    if (uart_num == uart1)
        tmp = uart1_rx_buf_p[uart_readptr[uart_num]++];
#endif
#if (UART2_EN && UART2_RXD_BUFFER_SIZE)
    if (uart_num == uart2)
        tmp = uart2_rx_buf_p[uart_readptr[uart_num]++];
#endif
#if (UART3_EN && UART3_RXD_BUFFER_SIZE)
    if (uart_num == uart3)
        tmp = uart3_rx_buf_p[uart_readptr[uart_num]++];
#endif
#if (UART4_EN && UART4_RXD_BUFFER_SIZE)
    if (uart_num == uart4)
        tmp = uart4_rx_buf_p[uart_readptr[uart_num]++];
#endif
    if (uart_readptr[uart_num] == rx_buf_size[uart_num])
    {
        uart_readptr[uart_num] = 0;
    }
    return tmp;
}

void serial_switch_output_gpio(UART_TYPE uart_num, UART_GPIO_NUM num)
{
#if UART1_EN
    if (uart_num == uart1)
    {
        P_SW1 &= 0X3F;
        P_SW1 |= num << 6;
    }
#endif
    if (num > 1)
        return;
#if UART2_EN
    if (uart_num == uart2)
    {
        P_SW2 &= ~0X01;
        P_SW2 |= num;
    }
#endif
#if UART3_EN
    if (uart_num == uart3)
    {
        P_SW2 &= ~0X02;
        P_SW2 |= num << 1;
    }
#endif
#if UART4_EN
    if (uart_num == uart4)
    {
        P_SW2 &= ~0X04;
        P_SW2 |= num << 2;
    }
#endif
}

#endif
